package com.feige.algorithm;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * @author 抖音号：程序员飞哥
 * B站：https://space.bilibili.com/490711252
 * @version 1.0
 * @Title: Study512出品
 * @Description: 我们有一个学习网站：https://www.study512.com
 */
public class CustomPreciseTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    /**
     * spring.shardingsphere.sharding.tables.study_user_order.table-strategy.standard.sharding-column=id
     * spring.shardingsphere.sharding.tables.study_user_order.table-strategy.standard.precise-algorithm-class-name=com.feige.algorithm.CustomTablePreciseShardingAlgorithm
     * 其实你可以理解：
     * - 当你在执行一个SQL的时候，会进行拦截处理。根据你配置的规则进行确定真实表或者数据源
     * - 如果是数据源的分片处理，就会先确定数据源
     * - 就会判断你的SQL中的表是不是需要被处理的shardingjdbc处理的（逻辑表），因为分片算法都是根据逻辑表来进行配置的。也就是：study_user_order
     * - 就会判断你的SQL中的条件是不是需要被处理的shardingjdbc处理的字段，也就是你的分片字段规则，也就是：id
     * - 然后根据字段的值进行规则换算，来确认你执行的真实表或者真实的数据源
     * @param tableNames
     * - 数据源集合或者是分片表的集合
     * - 主要点就在于：你当前自定义的分片策略是用于数据源还是表
     * - 如果是数据库--就是数据源集合
     * - 如果是表--就是表集合
     * @param preciseShardingValue
     * - 分片属性
     * logicTableName 逻辑表
     * columnName 分片健（表的字段），
     * value 具体的值
     * @return
     */
    @Override
    public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> preciseShardingValue) {
        for (String tableName : tableNames) {
            String value = preciseShardingValue.getValue() % tableNames.size() + "";
            //value是0，则进入0库表，1则进入1库表
            if (tableName.endsWith(value)) {
                return tableName;
            }
        }
        throw new IllegalArgumentException();
    }
}
